package com.njtoyo.taxi.admin.service.marketing.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.date.DateUtil;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.dynamic.datasource.annotation.DS;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.ObjectUtils;
import com.google.common.collect.Lists;
import com.njtoyo.taxi.admin.cache.PrimaryCachePutter;
import com.njtoyo.taxi.admin.handler.common.CustomerCouponHandler;
import com.njtoyo.taxi.admin.handler.common.DriverRewardHandler;
import com.njtoyo.taxi.admin.library.Const;
import com.njtoyo.taxi.admin.mapper.master.entity.*;
import com.njtoyo.taxi.admin.mapper.master.enums.DriverRewardCategory;
import com.njtoyo.taxi.admin.mapper.master.mapper.ActivityRewardLogMapper;
import com.njtoyo.taxi.admin.mapper.master.mapper.CustomerRegionActivityRuleMapper;
import com.njtoyo.taxi.admin.mapper.master.mapper.DriverRegionActivityRuleMapper;
import com.njtoyo.taxi.admin.mapper.master.mapper.RecommendationMapper;
import com.njtoyo.taxi.admin.rest.wrapper.business.driver.DriverRewardAddOrUpdateWrapper;
import com.njtoyo.taxi.admin.rest.wrapper.marketing.coupon.CustomerActivityRuleQueryWrapper;
import com.njtoyo.taxi.admin.service.business.driver.DriverRewardService;
import com.njtoyo.taxi.admin.service.marketing.CustomerActivityService;
import com.njtoyo.taxi.admin.utils.DateUtils;
import com.taxi.entity.common.RestResult;
import com.taxi.entity.common.ResultEnum;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections.MapUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.util.*;
import java.util.concurrent.CompletableFuture;

@Component
@Slf4j
@DS(Const.PRIMARY_DS)
public class CustomerActivityServiceImpl implements CustomerActivityService {
    @Resource
    private CustomerRegionActivityRuleMapper customerActivityMapper;

    @Resource
    private RecommendationMapper recommendationMapper;

    @Resource
    private DriverRewardService driverRewardService;

    @Resource
    private DriverRegionActivityRuleMapper driverRegionActivityRuleMapper;

    @Resource
    private ActivityRewardLogMapper activityRewardLogMapper;

    @Autowired
    private CustomerCouponHandler customerCouponHandler;

    @Resource
    private DriverRewardHandler driverRewardHandler;

    @Resource
    private PrimaryCachePutter primaryCachePutter;

    @Override
    public RestResult sendCustomerCoupon(CustomerActivityRuleQueryWrapper wrapper) {
        CustomerRegionActivityRule customerRuleByAdCode = customerActivityMapper.getCustomerRuleByAdCode(wrapper.getAdCode());
        JSONObject cou = new JSONObject();
        if(ObjectUtils.isNotEmpty(wrapper.getDriverId())) {
            Recommendation recommendation = new Recommendation();
            //更新司乘绑定
            LambdaQueryWrapper<Recommendation> recommendationWrapper = new LambdaQueryWrapper<>();
            recommendationWrapper.eq(Recommendation::getFromId, wrapper.getDriverId());
            recommendationWrapper.eq(Recommendation::getUserId, wrapper.getCustomerId());
            recommendation.setIsValid(false);
            //根据adcode查询乘客活动信息
            if (ObjectUtils.isEmpty(customerRuleByAdCode)) {
                recommendationMapper.update(recommendation, recommendationWrapper);
                log.info("无乘客优惠活动,乘客id:{}", wrapper.getCustomerId());
                return RestResult.failed("无乘客优惠活动", ResultEnum.NO_CUSTOMER_ACTICITY);
            }
            String detailSpecification = customerRuleByAdCode.getDetailSpecification();
            JSONObject jsonObject = JSONObject.parseObject(detailSpecification);
            BigDecimal totalAmount = jsonObject.getBigDecimal("totalAmount");
            //已发金额
            BigDecimal customerRewardValue = customerActivityMapper.countActivityAmount(0, 0, customerRuleByAdCode.getId());
            JSONObject coupon = jsonObject.getJSONObject("coupon");
            BigDecimal customerValue = coupon.getBigDecimal("value");
            if (null == customerRewardValue) {
                customerRewardValue = BigDecimal.ZERO;
            }
            if (totalAmount.compareTo(customerRewardValue) > 0) {
                //封顶大于已发
                //BigDecimal count = jsonObject.getBigDecimal("count");
                if (totalAmount.subtract(customerRewardValue).compareTo(customerValue) < 1) {
                    recommendationMapper.update(recommendation, recommendationWrapper);
                    log.info("优惠金额已满，无法再发放优惠券,乘客id:{},封顶金额:{},已发金额:{}", wrapper.getCustomerId(),totalAmount,customerRewardValue);
                    return RestResult.failed("优惠金额已满，无法再发放优惠券", ResultEnum.CAPPING_MONEY);
                }
            } else {
                recommendationMapper.update(recommendation, recommendationWrapper);
                log.info("优惠金额已满，无法再发放优惠券,乘客id:{},封顶金额:{},已发金额:{}", wrapper.getCustomerId(),totalAmount,customerRewardValue);
                return RestResult.failed("优惠金额已满，无法再发放优惠券", ResultEnum.CAPPING_MONEY);
            }
            cou.put("value",customerValue);
            cou.put("startTime",DateUtils.parseDateToStr("yyyy-MM-dd HH:mm:ss",new Date()));
            Integer day = coupon.getInteger("effectiveDay");
            cou.put("endTime", DateUtils.parseDateToStr("yyyy-MM-dd HH:mm:ss",DateUtil.offsetDay(new Date(),day)));
            //发放司机奖励
            CompletableFuture.runAsync(() -> {
                try {
                    //查询司机优惠活动
                    DriverRegionActivityRule driverRuleByAdCode = driverRegionActivityRuleMapper.getDriverRuleByAdCode(wrapper.getAdCode());
                    if (ObjectUtils.isNotEmpty(driverRuleByAdCode)) {
                        String driverDetailSpecification = driverRuleByAdCode.getDetailSpecification();
                        JSONObject driverObject = JSONObject.parseObject(driverDetailSpecification);
                        JSONObject completeOrderConfig = driverObject.getJSONObject("completeOrderConfig");
                        JSONObject reward = driverObject.getJSONObject("reward");
                        //发放金额
                        BigDecimal driverValue = reward.getBigDecimal("value");
                        //司机活动结束时间
                        String driverEndTime = completeOrderConfig.getString("endTime");
                        //乘客注册时间超过活动结束时间直接发放奖励
                        if (new Date().getTime() - DateUtils.parseDate(driverEndTime).getTime() > 0) {
                            //已发金额
                            BigDecimal driverRewardValue = customerActivityMapper.countActivityAmount(1, 1, driverRuleByAdCode.getId());
                            if (null == driverRewardValue) {
                                driverRewardValue = BigDecimal.ZERO;
                            }
                            //是否超过金额
                            if (driverObject.getBigDecimal("totalAmount").compareTo(driverRewardValue) > 0 &&
                                    driverObject.getBigDecimal("totalAmount").subtract(driverRewardValue).compareTo(driverValue) > 0) {
                                log.info("乘客注册超过活动时间发放司机奖励开始，司机id:{},乘客id:{}", wrapper.getDriverId(), wrapper.getCustomerId());
                            /*DriverRewardAddOrUpdateWrapper driverRewardAddWrapper = new DriverRewardAddOrUpdateWrapper();
                            driverRewardAddWrapper.setRewardAmount(driverValue);
                            driverRewardAddWrapper.setDriverIds(Lists.newArrayList(wrapper.getDriverId()));
                            driverRewardAddWrapper.setCategory(DriverRewardCategory.recommend);
                            RestResult driverAdd = driverRewardService.add(driverRewardAddWrapper);*/
                                Long driverRewardId = driverRewardHandler.sendDriverReward(wrapper.getDriverId(), driverValue);
                                //奖励日志
                                ActivityRewardLog activityRewardLog = new ActivityRewardLog();
                                activityRewardLog.setGrantedId(wrapper.getDriverId());
                                activityRewardLog.setRewardId(driverRewardId);
                                activityRewardLog.setRewardValue(driverValue);
                                activityRewardLog.setRewardCategory(1);
                                activityRewardLog.setRefId(driverRuleByAdCode.getId());
                                activityRewardLog.setActivityCategory(1);
                                activityRewardLog.setDriverRegionId(driverRuleByAdCode.getDriverRegionId());
                                activityRewardLog.setCreatedAt(new Date());
                                activityRewardLogMapper.insert(activityRewardLog);
                                log.info("乘客注册超过活动时间发放司机奖励完成，司机id:{},乘客id:{}", wrapper.getDriverId(), wrapper.getCustomerId());
                            } else {
                                log.info("已发奖励金额:{},封顶金额:{},单个司机奖励金额:{},司机id:{},乘客id:{}",
                                        driverRewardValue, driverObject.getBigDecimal("totalAmount"), driverValue, wrapper.getDriverId(), wrapper.getCustomerId());
                            }
                        } else {
                            log.info("注册乘客还在司机活动时间内，暂不发放司机奖励，司机id:{},乘客id:{}", wrapper.getDriverId(), wrapper.getCustomerId());
                        }
                    } else {
                        log.info("区域码:{},该区域暂无司机优惠活动", wrapper.getAdCode());
                    }
                } catch (Exception e) {
                    log.error("发放司机奖励异常:{}", e.getMessage());
                    throw new RuntimeException(e);
                }
            });
            //清理司机缓存
            primaryCachePutter.deleteDriverCacheById(wrapper.getDriverId());
        }else{
            if (ObjectUtils.isEmpty(customerRuleByAdCode)) {
                log.info("无乘客优惠活动,乘客id:{}", wrapper.getCustomerId());
                return RestResult.failed("无乘客优惠活动", ResultEnum.NO_CUSTOMER_ACTICITY);
            }
            String detailSpecification = customerRuleByAdCode.getDetailSpecification();
            JSONObject jsonObject = JSONObject.parseObject(detailSpecification);
            BigDecimal totalAmount = jsonObject.getBigDecimal("totalAmount");
            //已发金额
            BigDecimal customerRewardValue = customerActivityMapper.countActivityAmount(0, 0, customerRuleByAdCode.getId());
            JSONObject coupon = jsonObject.getJSONObject("coupon");
            BigDecimal customerValue = coupon.getBigDecimal("value");
            if (null == customerRewardValue) {
                customerRewardValue = BigDecimal.ZERO;
            }
            if (totalAmount.compareTo(customerRewardValue) > 0) {
                //封顶大于已发
                //BigDecimal count = jsonObject.getBigDecimal("count");
                if (totalAmount.subtract(customerRewardValue).compareTo(customerValue) < 1) {
                    log.info("优惠金额已满，无法再发放优惠券,乘客id:{},封顶金额:{},已发金额:{}", wrapper.getCustomerId(),totalAmount,customerRewardValue);
                    return RestResult.failed("优惠金额已满，无法再发放优惠券", ResultEnum.CAPPING_MONEY);
                }
            } else {
                log.info("优惠金额已满，无法再发放优惠券,乘客id:{},封顶金额:{},已发金额:{}", wrapper.getCustomerId(),totalAmount,customerRewardValue);
                return RestResult.failed("优惠金额已满，无法再发放优惠券", ResultEnum.CAPPING_MONEY);
            }
            cou.put("value",customerValue);
            cou.put("startTime",DateUtils.parseDateToStr("yyyy-MM-dd HH:mm:ss",new Date()));
            Integer day = coupon.getInteger("effectiveDay");
            cou.put("endTime", DateUtils.parseDateToStr("yyyy-MM-dd HH:mm:ss",DateUtil.offsetDay(new Date(),day)));
        }
        //发放乘客优惠券
        Long couponId = customerCouponHandler.sendCustomerCoupon(customerRuleByAdCode, wrapper.getCustomerId(), wrapper.getAdCode(),null);
        List<JSONObject> list = new ArrayList<>();
        cou.put("id",couponId);
        list.add(cou);
        return RestResult.success().add("coupon",list);
    }
}
